package com.dkm.ec.so.domain;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.dkm.base.api.service.IdGenerator;
import com.dkm.base.core.helper.SpringHelper;
import com.dkm.biz.domain.AbstractDomain;
import com.dkm.biz.gl.service.GlSwiftService;
import com.dkm.biz.ou.domain.Addr;
import com.dkm.biz.ou.persistence.entity.AddrPo;
import com.dkm.biz.ou.persistence.entity.ShopStatPoEnum;
import com.dkm.biz.ou.repository.AddrRepository;
import com.dkm.biz.ou.service.ShopStatStatService;
import com.dkm.ec.activity.adaptor.ActivitySkuAdaptor;
import com.dkm.ec.address.domain.UserAddress;
import com.dkm.ec.address.persistence.entity.UserAddressPo;
import com.dkm.ec.address.repository.UserAddressRepository;
import com.dkm.ec.cart.persistence.dao.CartItemDao;
import com.dkm.ec.cart.repository.CartItemRepository;
import com.dkm.ec.constants.SaleStatConstants;
import com.dkm.ec.sale.repository.SaleEntityStatRepository;
import com.dkm.ec.sale.service.SaleSkuStatService;
import com.dkm.ec.so.persistence.dao.SoEntityDao;
import com.dkm.ec.so.persistence.dao.SoItemDao;
import com.dkm.ec.so.persistence.entity.SoAddrPo;
import com.dkm.ec.so.persistence.entity.SoEntityPo;
import com.dkm.ec.so.persistence.entity.SoEntityPoEnum;
import com.dkm.ec.so.persistence.entity.SoInvoicePo;
import com.dkm.ec.so.persistence.entity.SoItemPo;
import com.dkm.ec.so.repository.SoAddrRepository;
import com.dkm.ec.so.repository.SoEntityRepository;
import com.dkm.ec.so.repository.SoInvoiceRepository;
import com.dkm.ec.so.repository.SoItemRepository;
import com.dkm.ec.stock.domain.Stock;
import com.dkm.ec.stock.persistence.entity.StockPo;
import com.dkm.ec.stock.repository.StockRepository;

/**
 * 对象功能:销售订单。 领域对象实体
 * 开发公司:dkm.com
 * 开发人员:ZHH
 * 创建时间:2017-05-19 15:50:21
 */
@SuppressWarnings("serial")
@Service
@Scope("prototype")
public class SoEntity extends AbstractDomain<String, SoEntityPo>{
	 
	 private SoEntityDao soEntityDao = null;
	 @Resource
	 private GlSwiftService glSwiftService;
	 @Resource
	 private SoEntityRepository soEntityRepository;
	 @Resource
	 private SoAddrRepository  soAddrRepository;
	 @Resource
	 private CartItemDao cartItemDao;
	 @Resource
	 private AddrRepository addrRepository;
	 @Resource
	 private SoItemRepository soItemRepository;
	 @Resource
	 private SoInvoiceRepository soInvoiceRepository;
	 @Resource
	 private StockRepository stockRepository;
	 @Resource
	 private CartItemRepository  cartItemRepository;
	 @Resource
	 private SaleEntityStatRepository saleEntityStatRepository;
	 @Resource
	 private SaleSkuStatService saleSkuStatService;
	 @Resource
	 private ShopStatStatService shopStatStatService;
	 @Resource
	 private SoItemDao soItemDao;
	@Resource
	 private ActivitySkuAdaptor activitySkuAdaptor;
	 @Resource
	 private IdGenerator IdGenerator;
	 @Resource
	 private UserAddressRepository userAddressRepository;

	protected void init(){
		soEntityDao = SpringHelper.getBean(SoEntityDao.class);
		setDao(soEntityDao);
	}

	public String createSoEntityOrder(int size, String userId, BigDecimal totalBigDecimal, String isFreightInsurance,
			String leaveWord, BigDecimal shippingAmount,String shopId, AddrPo addrPo) throws Exception {
		
		SoEntityPo soEntityPo = new SoEntityPo();
		String soNo = glSwiftService.nextId("order");
		soEntityPo.setSoNo(soNo);
		soEntityPo.setSoType("sales");
		soEntityPo.setReviewStatus("none");
		soEntityPo.setIsMain('Y');
		soEntityPo.setProdQty(size);
		soEntityPo.setCreateBy(userId);
		soEntityPo.setOtherAmount(new BigDecimal("0"));
		soEntityPo.setTotal(totalBigDecimal);
		soEntityPo.setSoStatus("awaiting_pay");
		soEntityPo.setIsHide('N');
		soEntityPo.setIsFreightInsurance(isFreightInsurance);
		soEntityPo.setLeaveWord(leaveWord);
		soEntityPo.setShippingAmount(shippingAmount);
		soEntityPo.setShopId(shopId);
		SoEntity soEntity =  soEntityRepository.newInstance(soEntityPo);
		soEntity.create();
		
	      SoAddrPo soAddrPo2 = new SoAddrPo();
		  BeanUtils.copyProperties(soAddrPo2, addrPo);
		  soAddrPo2.setSoId(soEntityPo.getId());
		  soAddrPo2.setOuAddrId(addrPo.getId());
		  SoAddr soAddr = soAddrRepository.newInstance(soAddrPo2);
		  soAddr.setNewFlag(true);
		  soAddr.create();
		
		  return soEntity.getId();
	}

	public void createMainSoEntity(String userId, String addrId, String carItemIds,
			List<SoEntityPo> soEntityPos, List<SoItemPo> soItemPos, SoEntityPo soEntityPo, List<SoInvoicePo> soInvoicePos) 
					throws Exception {
		SoEntity soEntityMain = soEntityRepository.newInstance(soEntityPo);
		soEntityMain.create();
		for(SoEntityPo soEntityPoSub : soEntityPos){
			SoEntity soEntitySub = soEntityRepository.newInstance(soEntityPoSub);
			soEntitySub.create();
			Integer totalSaleQyt = 0;
			
			for(SoItemPo soItemPo : soEntityPoSub.getSoItemPos()){
				SoItem soItem = soItemRepository.newInstance(soItemPo);
				soItem.create();
				totalSaleQyt +=soItemPo.getCount();
				
				
				//减库存
				if(org.springframework.util.StringUtils.hasLength(soItemPo.getActivityType())){
					activitySkuAdaptor.reduceStock(soItemPo);
				}else{
					StockPo stockPo = stockRepository.findBySkuId(soItemPo.getProdSkuId());
					stockPo.setQty(stockPo.getQty() - soItemPo.getCount());
					Stock stock = stockRepository.newInstance(stockPo);
					stock.save();
				}

				//商品销量统计
				saleSkuStatService.addProductStat(soItemPo.getProductId(), SaleStatConstants.TYPE_SALE, 
						soItemPo.getCount(),new BigDecimal(0));
				saleSkuStatService.addSkuStat(soItemPo.getProductId(), soItemPo.getProdSkuId(),SaleStatConstants.TYPE_SALE, 
						soItemPo.getCount(),new BigDecimal(0));
			}
			//统计去库存加销量
			shopStatStatService.addShopStat(soEntityPoSub.getShopId(),ShopStatPoEnum.stock_qty_,-totalSaleQyt);
			shopStatStatService.addShopStat(soEntityPoSub.getShopId(),ShopStatPoEnum.sale_qty_,totalSaleQyt);
		}
		Map<String,  List<SoItemPo>> soItemPosMap = getSkuIdsByProIds(soItemPos);
		for(String proids  : soItemPosMap.keySet()){	
			//订单数
			BigDecimal sales_totalSku = new BigDecimal(0);
			saleSkuStatService.addProductStat(proids, SaleStatConstants.ORDER_COUNT, 
					1,new BigDecimal(0));
			for(SoItemPo soItemPosItem : soItemPosMap.get(proids)){
				//订单数
				saleSkuStatService.addSkuStat(soItemPosItem.getProductId(), soItemPosItem.getProdSkuId(),SaleStatConstants.ORDER_COUNT, 
						1,new BigDecimal(0));
				BigDecimal skuBig =  sales_totalSku.add(soItemPosItem.getAmount()
		                 .multiply(new BigDecimal(soItemPosItem.getCount())));
				sales_totalSku = sales_totalSku.add(skuBig);
				//总销售价
				saleSkuStatService.addSkuStat(soItemPosItem.getProductId(), soItemPosItem.getProdSkuId(),SaleStatConstants.SALE_TOTAL, 
						0,skuBig);
			}
			saleSkuStatService.addProductStat(proids, SaleStatConstants.SALE_TOTAL, 
					0,sales_totalSku);
		}
		for(SoInvoicePo soInvoicePo : soInvoicePos){
			SoInvoice soInvoice = soInvoiceRepository.newInstance(soInvoicePo);
			soInvoice.create();
		}
		UserAddress userAddress=  userAddressRepository.load(addrId);
		if(userAddress != null){
			UserAddressPo userAddressPo =userAddress.getData();
			SoAddrPo soAddrPo2 = new SoAddrPo();
			soAddrPo2.setPrName(userAddressPo.getProvince());
			soAddrPo2.setCiName(userAddressPo.getCity());
			soAddrPo2.setArName(userAddressPo.getCounty());
			soAddrPo2.setAddr(userAddressPo.getDetailAddress());
			soAddrPo2.setPerson(userAddressPo.getName());
			soAddrPo2.setMobile(userAddressPo.getContactInformation());
			soAddrPo2.setId(IdGenerator.genSid());
		    soAddrPo2.setSoId(soEntityPo.getId());
		    soAddrPo2.setOuAddrId(addrId);
		    SoAddr soAddr = soAddrRepository.newInstance(soAddrPo2);
		    soAddr.setNewFlag(true);
			soAddr.create();
		}
		
		/* UserAddressPo userAddressPo = userAddressRepository.findByPartyid(OuOnlineHolder.getZmzUserId(request));
         UserAddressViewConverter userAddressViewConverter = new UserAddressViewConverter();
         SoAddrView userAddressView = userAddressViewConverter.converterSoAddrView(userAddressPo);
         baseAPIResult.setSoAddrView(userAddressView);*/
	/*	
		Addr addr =  addrRepository.load(addrId);
		AddrPo addrPo = addr.getData();
		SoAddrPo soAddrPo2 = new SoAddrPo();
		BeanUtils.copyProperties(soAddrPo2, addrPo);*/
		
		
	
		//删除购物车
		cartItemRepository.newInstance().destroyAndEntity(carItemIds);
	}

	public void deleteSoEntityAndParent(SoEntityPo soEntityPo) {
		setData(soEntityPo);
	    save();
	    Map<String,  Object> params = new HashMap<String, Object>();
	    params.put("whereSql", "soEntity.parent_id_='"+soEntityPo.getParentId()+"' and soEntity.is_hide_='N'");
	    List<SoEntityPo> subSoEntityPos =  soEntityRepository.findAll(params);
	    if(subSoEntityPos.size()  == 0){
	    	SoEntity soEntity = soEntityRepository.load(soEntityPo.getParentId());
	    	SoEntityPo parentSoEntityPo = soEntity.getData();
	    	parentSoEntityPo.setIsHide('Y');
	    	soEntityRepository.newInstance(parentSoEntityPo).save();
	    }
	}	 
	public void cancelSoEntityAndParent(SoEntityPo soEntityPo) {
		setData(soEntityPo);
	    save();
	    Map<String,  Object> params = new HashMap<String, Object>();
	    params.put("whereSql", "s.parent_id_='"+soEntityPo.getParentId()+"' s.so_status_='"+SoEntityPoEnum.cancelled.toString()+"'");
	    List<SoEntityPo> subSoEntityPos =  soEntityRepository.findAll(params);
	    if(subSoEntityPos.size()  == 0){
	    	SoEntity soEntity = soEntityRepository.load(soEntityPo.getParentId());
	    	SoEntityPo parentSoEntityPo = soEntity.getData();
	    	parentSoEntityPo.setSoStatus(SoEntityPoEnum.cancelled.toString());
	    	soEntityRepository.newInstance(parentSoEntityPo).save();
	    }
	   //恢复库存
	    Integer totalSaleQyt = 0;
	   List<SoItemPo> soItemPos = soItemRepository.findBySoEntityId(soEntityPo.getId());
	   for(SoItemPo soItemPo : soItemPos){
		   if(org.springframework.util.StringUtils.hasLength(soItemPo.getActivityType())){
				activitySkuAdaptor.returnStock(soItemPo);
		   }else {
			   StockPo stockPo = stockRepository.findBySkuId(soItemPo.getProdSkuId());
			   stockPo.setQty(stockPo.getQty() + soItemPo.getCount());
			   Stock stock = stockRepository.newInstance(stockPo);
			   stock.save();
		   }
			
			totalSaleQyt +=soItemPo.getCount();
			
			 //恢复统计	
			 saleSkuStatService.addProductStat(soItemPo.getProductId(), SaleStatConstants.TYPE_SALE_SUBDUCTION, 
						soItemPo.getCount(),new BigDecimal(0));
			 saleSkuStatService.addSkuStat(soItemPo.getProductId(), soItemPo.getProdSkuId(),SaleStatConstants.TYPE_SALE_SUBDUCTION, 
						soItemPo.getCount(),new BigDecimal(0));
	   }
	   Map<String,  List<SoItemPo>> soItemPosMap = getSkuIdsByProIds(soItemPos);
	   for(String proids  : soItemPosMap.keySet()){
				//订单数
				BigDecimal sales_totalSku = new BigDecimal(0);
				saleSkuStatService.addProductStat(proids, SaleStatConstants.ORDER_COUNT, 
						-1,new BigDecimal(0));
				for(SoItemPo soItemPosItem : soItemPosMap.get(proids)){
					//订单数
					saleSkuStatService.addSkuStat(soItemPosItem.getProductId(), soItemPosItem.getProdSkuId(),SaleStatConstants.ORDER_COUNT, 
							-1,new BigDecimal(0));
					BigDecimal skuBig =  sales_totalSku.add(soItemPosItem.getAmount()
			                 .multiply(new BigDecimal(soItemPosItem.getCount())));
					sales_totalSku = sales_totalSku.add(skuBig);
					//sales_total_
					saleSkuStatService.addSkuStat(soItemPosItem.getProductId(), soItemPosItem.getProdSkuId(),
							SaleStatConstants.SALE_TOTAL_SUBDUCTION, 
							0,skuBig);
				}
				saleSkuStatService.addProductStat(proids, SaleStatConstants.SALE_TOTAL_SUBDUCTION, 
						0,sales_totalSku);
			}
	       //统计加库存去销量
	      shopStatStatService.addShopStat(soEntityPo.getShopId(),ShopStatPoEnum.stock_qty_,totalSaleQyt);
	      shopStatStatService.addShopStat(soEntityPo.getShopId(),ShopStatPoEnum.sale_qty_,-totalSaleQyt);
	}
	public Map<String,  List<SoItemPo>> getSkuIdsByProIds(List<SoItemPo> soItemPos){
		Map<String,  List<SoItemPo>>  soItemPosMap = new HashMap<>();
	    Set<String> saleProIds = new HashSet<>();
		for(SoItemPo soItemPo : soItemPos){
			saleProIds.add(soItemPo.getProductId());
		}
		for(String proId : saleProIds){
			List<SoItemPo> soItemPos2s = new ArrayList<>();
			for(SoItemPo soItemPo : soItemPos){
				if(soItemPo.getProductId().equals(proId)){
					soItemPos2s.add(soItemPo);
				}
			}
			soItemPosMap.put(proId, soItemPos2s);
		}
		return soItemPosMap;
	}

	public void completed(SoEntityPo soEntityPo) {
		soEntityPo.setSoStatus("completed");
		setData(soEntityPo);
	    save();
	    Map<String,  Object> params = new HashMap<String, Object>();
	    params.put("whereSql", "soEntity.parent_id_='"+soEntityPo.getParentId()+"' and soEntity.so_status_!='completed'");
	    List<SoEntityPo> subSoEntityPos =  soEntityRepository.findAll(params);
	    if(subSoEntityPos.size()  == 0){
	    	SoEntity soEntity = soEntityRepository.load(soEntityPo.getParentId());
	    	SoEntityPo parentSoEntityPo = soEntity.getData();
	    	parentSoEntityPo.setSoStatus("completed");
	    	soEntityRepository.newInstance(parentSoEntityPo).save();
	    }
	    //item
		Map<String, Object> paramsItem = new HashMap<>();
		paramsItem.put("soEntityId", soEntityPo.getId());
		paramsItem.put("status", "completed");
		soItemDao.updateByKey("updateBySoentityId", paramsItem);
	}
}
